package com.evil.application.listener;

import cn.hutool.core.util.CharsetUtil;
import com.evil.account.api.RemoteLoginService;
import com.evil.application.pojo.dto.mq.ExcelImportMQReqDTO;
import com.evil.common.account.dto.LogoutReqDTO;
import com.evil.common.account.dto.user.UserEnterpriseBaseDTO;
import com.evil.common.account.enums.AppTypeEnum;
import com.evil.common.core.enums.BaseEnum;
import com.evil.common.core.exception.BusinessException;
import com.evil.common.family.constant.AppConstant;
import com.evil.common.family.enums.RCodeEnum;
import com.evil.common.rocketmq.entity.MqRequestAttributes;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.support.RocketMQMessageConverter;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.Map;

/**
 * 封装消息队列消费
 *
 * @author liyang
 * @date 2023-05-12 16:22
 */
@Slf4j
public abstract class AbstractRocketMqConsumer<T> implements RocketMQListener<MessageExt> {

    @Resource
    private RemoteLoginService remoteLoginService;

    public void onMessage(MessageExt messageExt) {
        MessageConverter messageConverter = new RocketMQMessageConverter().getMessageConverter();
        String str = new String(messageExt.getBody(), CharsetUtil.CHARSET_UTF_8);
        Object o = messageConverter.fromMessage(MessageBuilder.withPayload(str).build(), ExcelImportMQReqDTO.class);
        if (o == null || o.getClass() != this.getTClass()) {
            log.error("ImportAppOrderRocketMqConsumer | msg | error");
            throw new BusinessException(BaseEnum.RUN_ERROR);
        }
        // BEFORE 复制登录 避免互相与 生产者的登录信息 影响
        Map<String, String> properties = messageExt.getProperties();
        String userId = properties.get(AppConstant.HEADER_USER_ID);
        String enterpriseId = properties.get(AppConstant.HEADER_ENTERPRISE_ID);
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(enterpriseId)) {
            throw new BusinessException(RCodeEnum.ERROR_UNAUTHENTICATED);
        }
        String token = remoteLoginService.cpLoginToken(new UserEnterpriseBaseDTO(Long.valueOf(enterpriseId), Long.valueOf(userId)));
        properties.put(AppConstant.TOKEN_KEY, token);
        RequestContextHolder.setRequestAttributes(MqRequestAttributes.build(messageExt.getMsgId(), properties));

        this.consume(this.getTClass().cast(o));

        // AFTER 退出登录
        LogoutReqDTO logoutReqDTO = new LogoutReqDTO();
        logoutReqDTO.setAppType(AppTypeEnum.ENTERPRISE.getId());
        logoutReqDTO.setToken(token);
        remoteLoginService.logout(logoutReqDTO);
    }

    public abstract Class<T> getTClass();

    public abstract void consume(T t);
}
